//
//  Color.swift
//  
//
//  Created by bo wang on 2020/10/21.
//  Copyright © 2020 wangbo. All rights reserved.
//

import Foundation
import UIKit

let isDisplayP3Gamut = UIScreen.main.traitCollection.displayGamut == .P3

private extension Int64 {
    func duplicate4bits() -> Int64 {
        return (self << 4) + self
    }
}

public extension UIColor {
    private convenience init?(hex3: Int64, alpha: Float) {
        self.init(displayP3Red: CGFloat( ((hex3 & 0xF00) >> 8).duplicate4bits() ) / 255.0,
                  green: CGFloat( ((hex3 & 0x0F0) >> 4).duplicate4bits() ) / 255.0,
                  blue: CGFloat( ((hex3 & 0x00F) >> 0).duplicate4bits() ) / 255.0,
                  alpha: CGFloat(alpha))
    }

    private convenience init?(hex4: Int64, alpha: Float?) {
        self.init(displayP3Red: CGFloat( ((hex4 & 0xF000) >> 12).duplicate4bits() ) / 255.0,
                  green: CGFloat( ((hex4 & 0x0F00) >> 8).duplicate4bits() ) / 255.0,
                  blue: CGFloat( ((hex4 & 0x00F0) >> 4).duplicate4bits() ) / 255.0,
                  alpha: alpha.map(CGFloat.init(_:)) ?? CGFloat( ((hex4 & 0x000F) >> 0).duplicate4bits() ) / 255.0)
    }

    private convenience init?(hex6: Int64, alpha: Float) {
        self.init(displayP3Red: CGFloat( (hex6 & 0xFF0000) >> 16 ) / 255.0,
                  green: CGFloat( (hex6 & 0x00FF00) >> 8 ) / 255.0,
                  blue: CGFloat( (hex6 & 0x0000FF) >> 0 ) / 255.0,
                  alpha: CGFloat(alpha))
    }

    private convenience init?(hex8: Int64, alpha: Float?) {
        self.init(displayP3Red: CGFloat( (hex8 & 0xFF000000) >> 24 ) / 255.0,
                  green: CGFloat( (hex8 & 0x00FF0000) >> 16 ) / 255.0,
                  blue: CGFloat( (hex8 & 0x0000FF00) >> 8 ) / 255.0,
                  alpha: alpha.map(CGFloat.init(_:)) ?? CGFloat( (hex8 & 0x000000FF) >> 0 ) / 255.0)
    }

    convenience init?(hexString: String, alpha: Float? = nil) {
        var hex = hexString

        // Check for hash and remove the hash
        if hex.hasPrefix("#") {
            hex = String(hex[hex.index(after: hex.startIndex)...])
        }

        guard let hexVal = Int64(hex, radix: 16) else {
            return nil
        }

        switch hex.count {
        case 3:
            self.init(hex3: hexVal, alpha: alpha ?? 1.0)
        case 4:
            self.init(hex4: hexVal, alpha: alpha)
        case 6:
            self.init(hex6: hexVal, alpha: alpha ?? 1.0)
        case 8:
            self.init(hex8: hexVal, alpha: alpha)
        default:
            return nil
        }
    }
    
    convenience init?(hex: Int, alpha: Float = 1.0) {
        if (0x000000 ... 0xFFFFFF) ~= hex {
            self.init(hex6: Int64(hex), alpha: alpha)
        } else {
            return nil
        }
    }
}

extension UIColor {
    var hsba: (h: CGFloat, s: CGFloat, b: CGFloat, a: CGFloat) {
        var hue: CGFloat = 0
        var saturation: CGFloat = 0
        var brightness: CGFloat = 0
        var alpha: CGFloat = 0
        getHue(&hue,
               saturation: &saturation,
               brightness: &brightness,
               alpha: &alpha)
        return (hue, saturation, brightness, alpha)
    }
    
    var rgba: (r: CGFloat, g: CGFloat, b: CGFloat, a: CGFloat) {
        var red: CGFloat = 0
        var green: CGFloat = 0
        var blue: CGFloat = 0
        var alpha: CGFloat = 0
        getRed(&red,
               green: &green,
               blue: &blue,
               alpha: &alpha)
        return (red, green, blue, alpha)
    }
    
    // 调整颜色的亮度不高于最大亮度。亮度低于值时返回原颜色
    func setMaxBrightness(_ b: CGFloat) -> UIColor {
        let v = hsba
        if v.b <= b {
            return self
        }
        return UIColor(hue: v.h, saturation: v.s, brightness: b, alpha: v.a)
    }
}

extension CGColor {
    static func hex(_ string: String, alpha: Float? = nil) -> CGColor? {
        return UIColor(hexString: string, alpha: alpha)?.cgColor
    }
    static func hex(_ hex: Int, alpha: Float = 1.0) -> CGColor? {
        return UIColor(hex: hex, alpha: alpha)?.cgColor
    }
}

extension String {
    var hexColor: UIColor? {
        return UIColor(hexString: self)
    }
    
    var hexCGColor: CGColor? {
        return hexColor?.cgColor
    }
}

func HEX(_ string: String?, alpha: Float? = nil) -> UIColor? {
    return string != nil ? UIColor(hexString: string!, alpha: alpha) : nil
}

func HEX(_ hex: Int, alpha: Float = 1.0) -> UIColor? {
    return UIColor(hex: hex, alpha: alpha)
}

func RGB(_ r: Int, _ g: Int, _ b: Int, _ a: CGFloat = 1) -> UIColor {
    return UIColor(displayP3Red: CGFloat(r) / 255.0,
                   green: CGFloat(g) / 255.0,
                   blue: CGFloat(b) / 255.0,
                   alpha: a)
}
